<template>
    <el-table border row-key="taskId" ref="wl-gantt" class="wl-gantt" current-row-key="id" :data="selfData" :class="dateTypeClass" default-expand-all :tree-props="selfProps" header-row-class-name="wl-gantt-header" :row-class-name="tableRowClassName" >
        <el-table-column :resizable="false" fixed width="160" label="名称">
            <template slot-scope="scope">
                <span style="cursor: pointer;" @click="todetails(scope.row)">{{scope.row.name}}</span>
            </template>
        </el-table-column>
        <el-table-column :resizable="false" fixed width="100" :prop="selfProps.startDate" label="预计开始">
            <template slot-scope="scope">
                <span>{{scope.row[selfProps.startDate]}}</span>
            </template>
        </el-table-column>
        <el-table-column fixed :resizable="false" width="100" :prop="selfProps.endDate" label="预计结束">
            <template slot-scope="scope">
                <span>{{scope.row[selfProps.endDate]}}</span>
            </template>
        </el-table-column>
        <slot></slot>
        <el-table-column :resizable="false" v-for="year in titleDate" :key="year.id" :label="year.name">
            <el-table-column class-name="wl-gantt-item" v-for="month in year.children" :resizable="false" :key="month.id" :label="month.name">
                <el-table-column :resizable="false" class-name="wl-gantt-item" v-for="day in month.children" width="40" :key="day.id" :label="day.name">
                    <template slot-scope="scope">
                        <el-tooltip class="item" effect="dark" :content="`任务名字:${scope.row.name}\n
                              计划开始时间:${scope.row.startDate}\n
                              计划开始结束:${scope.row.startDate}\n
                              实际开始结束:${scope.row.workStartDate}\n
                              实际结束结束:${scope.row.workEndDate}\n`" placement="top">
                            <div :style="scope.row.matrix|backgroundstyle" :class="dayGanttType(scope.row, day.full_date)" style="display:flex" @click="ganttanclick(scope.row)">
                                <div :class="actualdayGanttType(scope.row, day.full_date)">
                                </div>
                            </div>
                        </el-tooltip>
                    </template>
                </el-table-column>
            </el-table-column>
        </el-table-column>
    </el-table>
</template>

<script>
import dayjs from "dayjs"; // 导入日期js
const uuidv4 = require("uuid-v4"); // 导入uuid生成插件
import isBetween from "dayjs/plugin/isBetween";
dayjs.extend(isBetween);
import {
    deepClone,
    treeToArray,
    flattenDeep,
    getMin,
    getMax,
} from "@/utils/array.js";
export default {
    name: "wlGantt",
    data() {
        return {
            curHeight: null,
            self_start_date: "", // 项目开始时间
            self_end_date: "", // 项目结束时间
            self_data_list: [], // 一维化后的gantt数据
            self_id: 1, // 自增id
            ganttData: [],
        };
    },
    filters: {
        backgroundstyle(val) {
            if (val == "01") {
                return "background:#ff5630";
            } else if (val == "02") {
                return "background:#E6A23C";
            } else if (val == "04") {
                return "background:#1a5eff";
            } else if (val == "05") {
                return "background:#36b37e";
            } else if (val == "00") {
                return "background:#c1c7d0";
            }
        },
    },
    props: {
        // gantt数据
        data: {
            type: Array,
            default: () => {
                return [];
            },
        },
        // 日期类型
        dateType: {
            type: String,
            default: "yearAndWeek", // monthAndDay,yearAndMonth,yearAndWeek
        },
        // 树表配置项
        props: Object,
        // 开始日期
        startDate: {
            type: [String, Object],
            required: true,
        },
        // 结束时间
        endDate: {
            type: [String, Object],
            required: true,
        },
        // 是否检查源数据符合规则，默认开启，如果源数据已遵循project规则，可设置为false以提高性能
        checkSource: {
            type: Boolean,
            default: true,
        },
        // 废弃：反而会因为频繁的判断而影响性能
        // 是否生成自增id并组成parents来满足树链的查询条件，如果数据本身已有自增id，可设置为false以提高性能
        // 如果设置为false，则数据内必须包含自增id字段：identityId，parents字段必须以`,`分割。
        // 字段名可通过props配置，自增id必须唯一并尽可能的短，如1，2，3...，parents应为祖先自增id通过`,`拼接直至父级
        recordParents: {
            type: Boolean,
            default: true,
        },
        // 是否使用id来作为自增id，如果是请保证id本来就简短的数字型而不是较长的字符串或guid
        treatIdAsIdentityId: {
            type: Boolean,
            default: false,
        },
        // 是否使用一维数据组成树
        /* arrayToTree: {
      type: Boolean,
      default: false
    } */
    },
    computed: {
        // 第一级日期
        titleDate() {
            // 分解开始和结束日期
            let start_date_spilt = dayjs(this.self_start_date).format("YYYY-M-D").split("-");
            let end_date_spilt = dayjs(this.self_end_date).format("YYYY-M-D") .split("-");
            let start_year = Number(start_date_spilt[0]);
            let start_mouth = Number(start_date_spilt[1]);
            let start_day = Number(start_date_spilt[2]);
            let end_year = Number(end_date_spilt[0]);
            let end_mouth = Number(end_date_spilt[1]);
            let end_day = Number(end_date_spilt[2]);
            // 日期数据盒子
            let dates = [
                {
                    name: `${start_year}年`,
                    date: start_year,
                    id: uuidv4(),
                    children: [],
                },
            ];
            // 处理年份
            let year_diff = end_year - start_year;
            // 年间隔为同一年
            if (year_diff === 0) {
                let mouths = []; // 处理月份
                let isLeap = this.isLeap(start_year);
                for (let i = start_mouth; i < end_mouth + 1; i++) {
                    let days = this.generationDays(start_year, i, isLeap);
                    mouths.push({
                        name: `${i}月`,
                        date: i,
                        full_date: `${start_year}-${i}`,
                        id: uuidv4(),
                        children: days,
                    });
                }
                dates[0].children = mouths;
                return dates;
            }
            // 处理开始月份
            let start_mouths = [];
            let startIsLeap = this.isLeap(start_year);
            for (let i = start_mouth; i < 13; i++) {
                let days = this.generationDays(start_year, i, startIsLeap);
                start_mouths.push({
                    name: `${i}月`,
                    date: i,
                    full_date: `${start_year}-${i}`,
                    id: uuidv4(),
                    children: days,
                });
            }
            // 处理结束月份
            let end_mouths = [];
            let endIsLeap = this.isLeap(end_year);
            for (let i = 1; i < end_mouth + 1; i++) {
                let days = this.generationDays(end_year, i, endIsLeap);
                end_mouths.push({
                    name: `${i}月`,
                    date: i,
                    full_date: `${end_year}-${i}`,
                    id: uuidv4(),
                    children: days,
                });
            }
            // 年间隔等于一年
            if (year_diff === 1) {
                dates[0].children = start_mouths;
                dates.push({
                    name: `${end_year}年`,
                    date: end_year,
                    children: end_mouths,
                    id: uuidv4(),
                });
                return dates;
            }
            // 年间隔大于1年
            if (year_diff > 1) {
                for (let i = 1; i < year_diff; i++) {
                    let item_year = start_year + i;
                    let isLeap = this.isLeap(item_year);
                    let month_and_day = this.generationMonths(
                        item_year,
                        isLeap
                    );
                    dates.push({
                        name: `${item_year}年`,
                        date: item_year,
                        id: uuidv4(),
                        children: month_and_day,
                    });
                }
                dates.push({
                    name: `${end_year}年`,
                    date: item_year,
                    children: end_mouths,
                    id: uuidv4(),
                });
                return dates;
            }
        },
        // 数据
        selfData() {
            let _data = this.data || [];
            this.self_data_list = flattenDeep(_data, this.selfProps.children);
            this.handleData(_data);
            return _data;
        },
        // 树表配置项
        selfProps() {
            return {
                hasChildren: "hasChildren",
                children: "children", // children字段
                name: "name", // 任务名称字段
                id: "id", // id字段
                pid: "pid", // pid字段
                startDate: "startDate", // 开始时间字段
                endDate: "endDate", // 结束时间字段
                identityId: "identityId",
                parents: "parents",
                pre: "pre", // 前置任务字段【注意：如果使用recordParents，则pre值应是目标对象的identityId字段(可配置)】
                ...this.props,
            };
        },
        // 根据日期类型改样式
        dateTypeClass() {
            if (this.dateType === "yearAndMonth") {
                return "year-and-month";
            } else if (this.dateType === "monthAndDay") {
                return "month-and-day";
            } else if (this.dateType === "yearAndWeek") {
                return "year-and-week";
            }
        },
    },
    mounted() {
        this.comeIn();
        // this.beforeMount()
        console.log(this.titleDate);
    },
    methods: {
        daychanggeName(data) {
            let day = this.getWeek(new Date(data.full_date)) + "周";
            return day;
        },
        // handerMethod({ row, column, rowIndex, columnIndex }) {
        //     if (rowIndex == 2 ) {
        //       if( columnIndex == 0){
        //         this.ganttData = [];
        //       }
        //         if (this.ganttData.indexOf(column.label) == -1) {
        //             this.ganttData.push(column.label);
        //         } else {
        //           //  return {display: 'none',width:'100%'}
        //             return { backgroundColor: "#fff", color: "#fff",borderRight: 'none'};
        //         }
        //     }
        // },
        getWeek(data) {
            let d1 = new Date(data);
            let d2 = new Date(data);
            d2.setMonth(0);
            d2.setDate(1);
            let rq = d1 - d2;
            let days = Math.ceil(rq / (24 * 60 * 60 * 1000));
            let num = Math.ceil(days / 7);
            return num;
        },

        //  getWeekInYear(date) {
        //   //  let date = new Date('2021-02-28')
        //     console.log(date)
        //     //判断该星期是否跨年，如果跨年就是第一周
        //     let weekStartDate = this.getWeekStartByDate(date) //一周开始时间
        //     console.log(weekStartDate,'weekStartDate')
        //     let endDate = this.getDateFromDay(weekStartDate, 6) //一周结束时间
        //     console.log(endDate,'endDate')
        //     if (weekStartDate.getFullYear() != endDate.getFullYear()) {
        //         console.log(endDate.getFullYear() + '年第1周')
        //         let num = 1
        //         return num
        //     }
        //     let d1 = new Date(date)
        //     let d2 = new Date(date)
        //     d2.setMonth(0)
        //     d2.setDate(1)
        //     d2 = getWeekStartByDate(d2)
        //     console.log(d2,'d2')
        //     let rq = d1 - d2
        //     let days = Math.ceil(rq / (24 * 60 * 60 * 1000)) + 1
        //     let num = Math.ceil(days / 7)
        //     console.log(endDate.getFullYear() + '年第' + num + '周')
        //     return num
        // },
        //  getWeekStartByDate(date) {
        //     let day = date.getDay()
        //     return getDateFromDay(date, -day)
        // },
        //  getDateFromDay(dayDate, day) {
        //     let date = new Date()
        //     date.setTime(dayDate.getTime() + day * 24 * 60 * 60 * 1000)
        //     return date
        // },
        //  beforeMount() {
        //   var _this = this
        //   window.onresize = () => {
        //     return (() => {
        //         var h = document.documentElement.clientHeight || document.body.clientHeight;
        //         _this.curHeight = h - 224//减去页面上固定高度height

        //     })();
        //   };
        // },
        comeIn() {
            var h =
                document.documentElement.clientHeight ||
                document.body.clientHeight;
            this.curHeight = h - 320; //减去页面上固定高度height
        },
        todetails(data) {
            this.$router.push({
                path: "/task/details",
                query: { id: data.taskId },
            });
        },
        tableRowClassName({ row, rowIndex }) {
            if (row.background == true) {
                return "warning-row";
            } else {
                return "success-row";
            }
        },
        ganttanclick(data) {
            console.log(data);
            this.$router.push({
                path: "/task/details",
                query: { id: data.taskId },
            });
        },
        /**
         * 开始时间改变
         * row: object 当前行数据
         */
        startDateChange(row) {
            // 如果将开始时间后移，结束时间也应后移
            let _delay = this.timeIsBefore(
                row._oldStartDate,
                row[this.selfProps.startDate]
            );
            if (_delay) {
                row[this.selfProps.endDate] = this.timeAdd(
                    row[this.selfProps.endDate],
                    row._cycle
                );
            }
            // 如果开始早于项目开始，则把项目开始提前
            let _early_project_start = this.timeIsBefore(
                row[this.selfProps.startDate],
                this.self_start_date
            );
            if (_early_project_start) {
                this.self_start_date = row[this.selfProps.startDate];
            }
        },
        /**
         * 结束时间改变
         * row: object 当前行数据
         */
        endDateChange(row) {
            // 如果开始晚于结束，提示
            /* if (
        this.timeIsBefore(
          row[this.selfProps.endDate],
          row[this.selfProps.startDate]
        )
      ) {
        row[this.selfProps.startDate] = row._oldStartDate;
        this.$message({
          showClose: true,
          message: "开始时间不可以晚于结束时间",
          type: "error"
        });
        return;
      } */
        },
        /**
         * 查询目标是否在父级链或者全部子集中
         * item 当前节点
         * pre 前置节点
         */
        targetInParentsOrChildren(item, pre) {
            let _parents = item._parents.split(",");
            let _children = item._all_children.map((i) => i._identityId);
            return _children.concat(_parents).some((i) => i == pre._identityId);
            /* let _parents = item[this.selfProps.parents].split(",").filter(i => !!i);
      let _children = item._all_children.map(i => i[this.selfProps.identityId]);
      return _children.push(..._parents).some(i => i == item[this.selfProps.pre]); */
        },
        // 以下是表格-日期-gantt生成函数----------------------------------------生成gantt表格-------------------------------------
        /**
         * 生成月份函数
         * year: Number 当前年份
         * isLeap: boolean 是否闰年
         */
        generationMonths(year, isLeap) {
            let months = [];
            for (let i = 1; i < 13; i++) {
                let days = this.generationDays(year, i, isLeap);
                months.push({
                    name: `${i}月`,
                    date: i,
                    full_date: `${year}-${i}`,
                    children: days,
                    id: uuidv4(),
                });
            }
            return months;
        },
        /**
         * 生成日期函数
         * year: Number 当前年份
         * month: Number 当前月份
         * isLeap: boolean 是否闰年
         */
        generationDays(year, month, isLeap) {
            let big_month = [1, 3, 5, 7, 8, 10, 12].includes(month);
            let small_month = [4, 6, 9, 11].includes(month);
            let dates_num = big_month
                ? 32
                : small_month
                ? 31
                : isLeap
                ? 30
                : 29;
            let days = [];
            for (let i = 1; i < dates_num; i++) {
                days.push({
                    date: i,
                    name: `${i}`,
                    id: uuidv4(),
                    full_date: `${year}-${month}-${i}`,
                });
            }
            return days;
        },
        /**
         * 是否闰年函数
         * year: Number 当前年份
         */
        isLeap(year) {
            return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
        },
        /**
         * 当前日期gantt状态
         * row: object 当前行信息
         * date: string 当前格子日期
         * unit: string 时间单位，以天、月、年计算
         */
        dayGanttType(row, date, unit = "days") {
            let start_date = row[this.selfProps.startDate];
            let end_date = row[this.selfProps.endDate];
            //判断 开始时间与结束时间是否在full_date(单格时间内)
            let between = dayjs(date).isBetween(start_date, end_date, unit);
            if (between) {
                return "wl-item-on";
            }
            let start = dayjs(start_date).isSame(date, unit);
            let end = dayjs(end_date).isSame(date, unit);
            if (start && end) {
                return "wl-item-on wl-item-full";
            }
            if (start) {
                return "wl-item-on wl-item-start";
            }
            if (end) {
                return "wl-item-on wl-item-end";
            }
        },
        actualdayGanttType(row, date, unit = "days") {
            let start_date = row.workStartDate;
            let end_date;
            if (row.status == "08") {
                end_date = row.workEndDate;
            } else {
                end_date = row.nowDate;
            }
            //判断 开始时间与结束时间是否在full_date(单格时间内)
            let between = dayjs(date).isBetween(start_date, end_date, unit);
            if (between) {
                return "wl-item-on-actual";
            }
            let start = dayjs(start_date).isSame(date, unit);
            let end = dayjs(end_date).isSame(date, unit);
            if (start && end) {
                return "wl-item-on-actual wl-item-full";
            }
            if (start) {
                return "wl-item-on-actual wl-item-start";
            }
            if (end) {
                return "wl-item-on-actual wl-item-end";
            }
        },
        // 以下是时间计算类函数 ------------------------------------------------------时间计算---------------------------------------
        /**
         * 计算时差
         * startDate：开始时间
         * endDate：结束时间
         * unit：单位 days、months、yesrs
         */
        timeDiffTime(startDate, endDate, unit = "days") {
            return dayjs(endDate).diff(startDate, unit);
        },
        /**
         * 比较时间，是否之前
         * startDate：开始时间
         * endDate：结束时间
         * unit：单位 days、months、yesrs
         */
        timeIsBefore(startDate, endDate, unit = "days") {
            return dayjs(startDate).isBefore(endDate, unit);
        },
        /**
         * 时间加计算函数
         * date：原时间
         * num：需要增加的时间数量
         * nuit：增加时间的单位 day year
         */
        timeAdd(date, num = 1, nuit = "day", format = "YYYY-MM-DD") {
            return dayjs(date).add(num, nuit).format(format);
        },
        /**
         * 时间格式化函数
         * date 需要格式化的数据
         * format 格式化的格式
         */
        timeFormat(date, format = "YYYY-MM-DD") {
            return dayjs(date).format(format);
        },
        // 以下为输出数据函数 --------------------------------------------------------------输出数据------------------------------------
        emitTimeChange(item) {
            this.$emit("timeChange", item);
            this.$nextTick(() => {
                this.$set(
                    item,
                    "_oldStartDate",
                    item[this.selfProps.startDate]
                );
                this.$set(item, "_oldEndDate", item[this.selfProps.endDate]);
            });
        },
        // 处理外部数据 ---------------------------------------------------------------原始数据处理-------------------------------------
        handleData(data, parent = null, level = 0) {
            level++;
            data.forEach((i) => {
                this.$set(i, "_parent", parent); // 添加父级字段
                this.$set(i, "_level", level); // 添加层级字段
                if (!i._oldStartDate) {
                    this.$set(i, "_oldStartDate", i[this.selfProps.startDate]);
                }
                if (!i._oldEndDate) {
                    this.$set(i, "_oldEndDate", i[this.selfProps.endDate]);
                }
                // 当结束时间早于开始时间时，自动处理结束时间为开始时间延后一天
                let _end_early_start = this.timeIsBefore(
                    i[this.selfProps.endDate],
                    i[this.selfProps.startDate]
                );
                if (_end_early_start) {
                    this.$set(
                        i,
                        this.selfProps.endDate,
                        i[this.selfProps.startDate]
                    );
                    this.$set(i, "_cycle", 1); // 添加工期字段
                    this.emitTimeChange(i); // 将发生时间更新的数据输出
                } else {
                    let _time_diff = this.timeDiffTime(
                        i[this.selfProps.startDate],
                        i[this.selfProps.endDate]
                    );
                    this.$set(i, "_cycle", _time_diff + 1); // 添加工期字段
                } // 添加工期字段
                // 如果当前节点的开始时间早于父节点的开始时间，则将开始时间与父节点相同
                this.parentStartDateToChild(i);
                // 校验结束时间是否晚于子节点，如不则将节点结束时间改为最晚子节点
                this.childEndDateToParent(i);
                // 添加自增id字段及树链组成的parents字段
                this.recordIdentityIdAndParents(i);
                if (Array.isArray(i[this.selfProps.children])) {
                    this.$set(i, "_isLeaf", false); // 添加是否叶子节点字段
                    let _all_children = flattenDeep(
                        i[this.selfProps.children],
                        this.selfProps.children
                    );
                    this.$set(i, "_all_children", _all_children); // 添加全部子节点字段
                    this.handleData(i[this.selfProps.children], i, level);
                } else {
                    this.$set(i, "_isLeaf", true); // 添加是否叶子节点字段
                    this.$set(i, "_all_children", []); // 添加全部子节点字段
                }
                // 处理前置任务
                this.handlePreTask(i);
            });
        },
        // 取父节点开始时间给早于父节点开始时间的子节点
        parentStartDateToChild(item) {
            if (!item._parent) return;
            // 如果子节点时间早于父节点，则将子节点开始时间后移至父节点开始时间,并将结束时间平移【即工期不变】
            let _child_early_parent = this.timeIsBefore(
                item[this.selfProps.startDate],
                item._parent[this.selfProps.startDate]
            );
            if (_child_early_parent) {
                // 修正子节点开始时间
                this.$set(
                    item,
                    this.selfProps.startDate,
                    item._parent[this.selfProps.startDate]
                );
                // 修正子节点结束时间
                let _to_endDate = this.timeAdd(
                    item[this.selfProps.startDate],
                    item._cycle
                );
                this.$set(item, this.selfProps.endDate, _to_endDate);
                this.emitTimeChange(item); // 将发生时间更新的数据输出
            }
        },
        // 取数组结束时间最大值，如果最大值比父级结束时间大，更新父级结束时间
        childEndDateToParent(item) {
            if (!Array.isArray(item[this.selfProps.children])) return;
            let _child_max = getMax(
                item[this.selfProps.children],
                this.selfProps.endDate,
                true
            ); // 取子节点中最晚的结束时间
            let _parent_end = dayjs(item[this.selfProps.endDate]).valueOf();
            if (_child_max > _parent_end) {
                // 如果子节点结束时间比父节点晚，则将父节点结束时间退后
                this.$set(
                    item,
                    this.selfProps.endDate,
                    this.timeFormat(_child_max)
                );
                this.emitTimeChange(item); // 将发生时间更新的数据输出
            }
        },
        // 处理前置任务节点
        handlePreTask(item) {
            if (!item[this.selfProps.pre]) return;
            // 找到前置目标节点
            let _pre_target = this.self_data_list.find(
                (i) => i[this.selfProps.id] == item[this.selfProps.pre]
            );
            if (!_pre_target) return;
            let is_pre_standard = this.targetInParentsOrChildren(
                item,
                _pre_target
            );
            if (is_pre_standard) return;
            // 查看是否需要根据前置时间，如果不符合规则，更新后置时间
            let _start_early_prvend = this.timeIsBefore(
                item[this.selfProps.startDate],
                _pre_target[this.selfProps.endDate]
            );
            if (_start_early_prvend) {
                let _cycle = item._cycle - 1;
                let _to_startDate = this.timeAdd(
                    _pre_target[this.selfProps.endDate],
                    1
                );
                let _to_endDate = this.timeAdd(_to_startDate, _cycle);
                this.$set(item, this.selfProps.startDate, _to_startDate);
                this.$set(item, this.selfProps.endDate, _to_endDate);
            }
        },
        // 处理数据生成自增id和树链parents
        recordIdentityIdAndParents(item) {
            // if (!this.recordParents) return;
            if (this.treatIdAsIdentityId) {
                let _parents = item._parent
                    ? item._parent._parents +
                      "," +
                      item._parent[this.selfProps.id]
                    : "";
                this.$set(item, "_parents", _parents);
                this.$set(item, "_identityId", item[this.selfProps.id]);
                return;
            }
            // 添加自增id
            this.$set(item, "_identityId", this.self_id);
            this.self_id++;
            // 添加parents字段
            let _parents = item._parent
                ? item._parent._parents + "," + item._parent._identityId
                : "";
            this.$set(item, "_parents", _parents);
        },
        // 简洁处理数据
        terseHandleData(data, parent = null, level = 0) {
            level++;
            data.forEach((i) => {
                this.$set(i, "_parent", parent); // 添加父级字段
                this.$set(i, "_level", level); // 添加层级字段
                let _time_diff = this.timeDiffTime(
                    i[this.selfProps.startDate],
                    i[this.selfProps.endDate]
                );
                i._cycle = _time_diff + 1;
                if (!i._oldStartDate) {
                    // 添加开始时间字段
                    this.$set(i, "_oldStartDate", i[this.selfProps.startDate]);
                }
                if (!i._oldEndDate) {
                    // 添加结束字段时间
                    this.$set(i, "_oldEndDate", i[this.selfProps.endDate]);
                }
                // 添加自增id字段及树链组成的parents字段
                this.recordIdentityIdAndParents(i);
                if (Array.isArray(i[this.selfProps.children])) {
                    this.$set(i, "_isLeaf", false); // 添加是否叶子节点字段
                    let _all_children = flattenDeep(
                        i[this.selfProps.children],
                        this.selfProps.children
                    );
                    this.$set(i, "_all_children", _all_children); // 添加全部子节点字段
                    this.terseHandleData(i[this.selfProps.children], i, level);
                } else {
                    this.$set(i, "_isLeaf", true); // 添加是否叶子节点字段
                }
                // 处理前置任务
                this.handlePreTask(i);
            });
        },
    },
    watch: {
        startDate(val) {
            this.self_start_date = val;
        },
        endDate(val) {
            this.self_end_date = val;
        },
    },
    created() {
        this.self_start_date = this.startDate;
        this.self_end_date = this.endDate;
    },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
$gantt_item: 16px;
$gantt_item_half: 8px;

.wl-gantt {
    .wl-gantt-header > th {
        text-align: center;
    }

    .wl-gantt-item {
        position: relative;
        transition: all 0.3s;
        > .cell {
            padding: 0;
        }
    }

    .u-full.el-input {
        width: 100%;
    }

    .wl-item-on {
        position: absolute;
        top: 50%;
        left: 0;
        right: -1px;
        margin-top: -$gantt_item_half;
        height: $gantt_item;
        background: #409eff;
        transition: all 0.4s;
    }

    .wl-item-start {
        left: 50%;
        // &:after {
        //   position: absolute;
        //   top: $gantt_item;
        //   left: 0;
        //   z-index: 1;
        //   content: "";
        //   width: 0;
        //   height: 0;
        //   border-color: #008c00 transparent transparent;
        //   // border-color: #409eff transparent transparent;
        //   border-width: 6px 6px 6px 0;
        //   border-style: solid;
        // }
    }

    .wl-item-end {
        right: 50%;
        // &:after {
        //   position: absolute;
        //   top: $gantt_item;
        //   right: 0;
        //   z-index: 1;
        //   content: "";
        //   width: 0;
        //   height: 0;
        //   // border-color: transparent #409eff;
        //   border-color: transparent #000;
        //   border-width: 0 6px 6px 0;
        //   border-style: solid;
        // }
    }

    .wl-item-full {
        left: 0;
        right: 0;
        // &:before {
        //   position: absolute;
        //   top: $gantt_item;
        //   left: 0;
        //   z-index: 1;
        //   content: "";
        //   width: 0;
        //   height: 0;
        //   border-color: #409eff transparent transparent;
        //   border-width: 6px 6px 6px 0;
        //   border-style: solid;
        // }
        // &:after {
        //   position: absolute;
        //   top: $gantt_item;
        //   right: 0;
        //   z-index: 1;
        //   content: "";
        //   width: 0;
        //   height: 0;
        //   border-color: transparent #409eff;
        //   border-width: 0 6px 6px 0;
        //   border-style: solid;
        // }
    }
}

.year-and-month {
    .wl-item-start {
        left: 5%;
        // &:after {
        //   position: absolute;
        //   top: $gantt_item;
        //   left: 0;
        //   z-index: 1;
        //   content: "";
        //   width: 0;
        //   height: 0;
        //   border-color: #409eff transparent transparent;
        //   border-width: 6px 6px 6px 0;
        //   border-style: solid;
        // }
    }

    .wl-item-end {
        right: 5%;
        // &:after {
        //   position: absolute;
        //   top: $gantt_item;
        //   right: 0;
        //   z-index: 1;
        //   content: "";
        //   width: 0;
        //   height: 0;
        //   border-color: transparent #409eff;
        //   border-width: 0 6px 6px 0;
        //   border-style: solid;
        // }
    }

    .wl-item-full {
        left: 0;
        right: 0;
        // &:before {
        //   position: absolute;
        //   top: $gantt_item;
        //   left: 0;
        //   z-index: 1;
        //   content: "";
        //   width: 0;
        //   height: 0;
        //   border-color: #409eff transparent transparent;
        //   border-width: 6px 6px 6px 0;
        //   border-style: solid;
        // }
        // &:after {
        //   position: absolute;
        //   top: $gantt_item;
        //   right: 0;
        //   z-index: 1;
        //   content: "";
        //   width: 0;
        //   height: 0;
        //   border-color: transparent #409eff;
        //   border-width: 0 6px 6px 0;
        //   border-style: solid;
        // }
    }
}
.wl-item-on-actual {
    position: absolute;
    left: 0;
    top: 50%;
    width: 100%;
    // height: 50%;
    height: 8px;
    background-color: #008c8c;
    // background-color: #46D8AB;
    // &:before {
    //   position: absolute;
    //   top: $gantt_item;
    //   left: 0;
    //   z-index: 1;
    //   content: "";
    //   width: 0;
    //   height: 0;
    //   border-color: #008c00 transparent transparent;
    //   border-width: 6px 6px 6px 0;
    //   border-style: solid;
    // }
    // &:after {
    //   position: absolute;
    //   top: $gantt_item;
    //   right: 0;
    //   z-index: 1;
    //   content: "";
    //   width: 0;
    //   height: 0;
    //   border-color: transparent #008c00;
    //   // border-width: 0 6px 6px 0;
    //   border-style: solid;
    // }
    // border-radius: 5px; ;
}
.el-table .warning-row {
    background: #fff;
}

.el-table .success-row {
    background: rgb(240, 240, 240);
}
.el-table .el-table__cell {
    padding: 1px 0px !important;
}
.el-table th.el-table__cell > .cell {
    padding-left: 0px !important;
    padding-right: 0px !important;
}
</style>
